//! self的相关方法实现
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;

use self::orm_field_impl::TinyOrmFieldSumInfo;

/// select fields生成
mod orm_field_impl;
/// join相关处理
mod orm_join_impl;
/// pk主键相关方法实现
mod orm_pk_impl;
/// 结构体字段解析
mod struct_field_parse;

/// 结构体数据表字段信息
#[derive(Clone, Debug)]
pub(crate) struct TinyOrmStructInfo {
    // 生成的相关方法
    pub(crate) token: TokenStream2,
    // 主键相关where sql
    pub(crate) pk_where_sql: String,
    // JOIN sql
    pub(crate) select_join_sql: Option<String>,
    // select field sql
    pub(crate) select_field: String,
    // update field sql
    pub(crate) update_set_field: String,
}

pub(super) fn impl_instance_method(ast: &syn::DeriveInput, table_name: &str) -> TinyOrmStructInfo {
    // 解析struct 字段为orm字段信息
    let orm_field_data_list = struct_field_parse::TinyOrmFieldData::parse_orm_field_info(ast);

    // 生成主键代码
    let orm_pk_impl::TinyOrmPkSumInfo {
        pk_where_sql,
        token: pk_token,
        pk_self_fields,
    } = orm_pk_impl::impl_struct_orm_pk(&orm_field_data_list, table_name);

    // 解析join字段信息及join方法
    if let Some(orm_join_impl::TinyOrmJoinSumInfo {
        fields: select_join_fields,
        join: join_sql,
        token: join_token,
        join_self_fields,
    }) = orm_join_impl::impl_orm_join(&orm_field_data_list, &pk_self_fields, table_name)
    {
        // 生成非join和pk字段信息
        let TinyOrmFieldSumInfo {
            select_fields_sql: table_select_fields,
            update_set_fields_sql: table_update_fields,
            update_all_and_insert_token: update_all_token,
        } = orm_field_impl::impl_orm_field(
            &orm_field_data_list,
            &pk_self_fields,
            Some(&join_self_fields),
            table_name,
        );

        TinyOrmStructInfo {
            token: quote! {
                #pk_token
                #join_token
                #update_all_token
            },
            pk_where_sql,
            select_join_sql: Some(join_sql),
            select_field: format!("{}, {}", table_select_fields, select_join_fields),
            update_set_field: table_update_fields,
        }
    } else {
        // 生成非join和pk字段信息
        let TinyOrmFieldSumInfo {
            select_fields_sql: table_select_fields,
            update_set_fields_sql: table_update_fields,
            update_all_and_insert_token: update_all_token,
        } = orm_field_impl::impl_orm_field(&orm_field_data_list, &pk_self_fields, None, table_name);

        TinyOrmStructInfo {
            token: quote! {
                #pk_token
                #update_all_token
            },
            pk_where_sql,
            select_join_sql: None,
            select_field: table_select_fields,
            update_set_field: table_update_fields,
        }
    }
}
